package redecolaborativa.server.gerentes;



import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

import redecolaborativa.server.excecoes.*;
import redecolaborativa.server.sistema.Usuario;


public class GerenciadorDeAmigos implements Serializable {
	private static final long serialVersionUID = 1L;
	private List<Usuario> amigos, solicitacoesDeAmizade;
	
	public GerenciadorDeAmigos() {
		amigos = new LinkedList<Usuario>();
		solicitacoesDeAmizade = new LinkedList<Usuario>();
	}
	
	/**
	 * Retorna a copia da lista de amigos de um usuario.
	 * @return A copia da lista de amigos de um usuario.
	 */
	public List<Usuario> getAmigos(){
		return new LinkedList<Usuario>(amigos);
	}
	
	/**
	 * Recupera uma copia das solicitacoes de amizade de um usuario
	 * @return Copia das solicitacoes de amizade de um usuario
	 */
	public List<Usuario> getSolicitacoesDeAmizade() {
		return new LinkedList<Usuario>(solicitacoesDeAmizade);
	}
	
	/**
	 * Requisita a amizade de um usuario a outro.
	 * @param requisitante Usuario que requisita a amizade.
	 * @param requisitado Usuario requisitado da amizade.
	 * @throws AmigoJaExisteException
	 * @throws RequisicaoInvalidaException
	 */
	public void requisitaAmizade(Usuario requisitante, Usuario requisitado) throws AmigoJaExisteException, RequisicaoInvalidaException {
		if(contem(requisitado)) {
			throw new AmigoJaExisteException("Os usuários já são amigos");
		} if(requisitado.gerenteDeAmigos().solicitacoesDeAmizade.contains(requisitante)) {
			throw new RequisicaoInvalidaException("Requisição já solicitada");
		} 
		requisitado.gerenteDeAmigos().solicitacoesDeAmizade.add(requisitante);
	}
	
	/**
	 * Adiciona um usuario a lista de amigos.
	 * @param Usuario a ser adicionado
	 * @return True caso o usuario for adicionado ou False caso o usuario nao for adicionado
	 * @throws AmigoJaExisteException 
	 * @throws RequisicaoInvalidaException 
	 * @throws InterruptedException 
	 */
	public void adiciona(Usuario aprovador, Usuario amigo) throws AmigoJaExisteException, RequisicaoInvalidaException {
		if (contem(amigo) || amigo.gerenteDeAmigos().contem(aprovador)) {
			throw new AmigoJaExisteException("Os usuários já são amigos");
		} if (!this.solicitacoesDeAmizade.contains(amigo)) {
			throw new RequisicaoInvalidaException("Requisição de amizade inexistente");
		}
		amigos.add(amigo);
		amigo.gerenteDeAmigos().amigos.add(aprovador);
		this.solicitacoesDeAmizade.remove(amigo);
	}
	
	/**
	 * Rejeita a amizade que foi requisitada removendo da lista de solicitacoes.
	 * @param Usuario a ser rejeitado
	 */
	public void rejeitarAmizade(Usuario usuario) {
		this.solicitacoesDeAmizade.remove(usuario);
	}
	
	/**
	 * Remove um usuario da lista de amigos.
	 * @param Usuario a ser removido
	 * @return True caso o usuario for removido e false em caso contrario
	 * @throws UsuarioInexistenteException 
	 */
	public void remove(Usuario usuario) throws UsuarioInexistenteException {
		if (!contem(usuario)) {
			throw new UsuarioInexistenteException("Amizade inexistente");
		} 
		this.amigos.remove(usuario);
	}
	
	/**
	 * Verifica se a lista de amigos contem um determinado Usuario.
	 * @param Usuario a ser verificado
	 * @return True se ele esta na lista de amigos ou false caso nao esteja
	 */
	public boolean contem(Usuario usuario) {
		return amigos.contains(usuario);
	}	
}